import 'dart:convert';

import 'package:inmotion_pro/pages/models/realtime_item.dart';
import 'package:inmotion_pro/pages/models/user_model.dart';
import 'package:inmotion_pro/pages/models/vehicle_model.dart';
import 'package:inmotion_pro/pages/others/common_enum/tbox_status_type.dart';
import 'package:inmotion_pro/service/log_service.dart';
import 'package:inmotion_pro/service/global_service.dart';
import 'package:inmotion_pro/service/user_service.dart';
import 'package:ble_helper_plugin/library.dart';
import 'package:flutter/material.dart';
import 'package:inmotion_pro/utils/utils.dart';

mixin CacheMixin {
  // 新增用户
  Future<bool> cacheMixinAddUser(UserModel userModel) async {
    bool success = await UserService.to.newUser(userModel.toMap());
    await cacheMixinRefreshCacheUserInfo();
    return Future(() => success);
  }

  // 更新缓存中的用户信息
  Future<bool> cacheMixinUpdateUser(
    int uid, {
    String? token,
    String? nickName,
    String? signature,
    String? avatar,
    String? phone,
    String? email,
    bool? isSelected,
  }) async {
    // 更新缓存中的token
    bool updateState = await UserService.to.updateUser(
      uid,
      token: token,
      nickName: nickName,
      signature: signature,
      avatar: avatar,
      isSelected: isSelected,
      phone: phone,
      email: email,
    );
    // 刷新缓存的用户信息
    await cacheMixinRefreshCacheUserInfo();
    return Future(() => updateState);
  }

  // 获取用户信息
  Future<UserModel> cacheMixinGetUserInfo() async {
    await cacheMixinRefreshCacheUserInfo();
    return Future(() => GlobalService.to.cacheUserInfo.value);
  }

  // 删除缓存中的refreshToken，让用户重新登录
  Future<bool> mixinRemoveCacheRefreshToken() async {
    // 移除缓存中的refreshToken
    bool updateState = await UserService.to.updateUser(
      GlobalService.to.cacheUserInfo.value.uid,
      token: '',
      xAuth: '',
    );
    // 刷新缓存的用户信息
    await cacheMixinRefreshCacheUserInfo();
    return Future(() => updateState);
  }

  // 刷新缓存的用户信息
  cacheMixinRefreshCacheUserInfo() async {
    // 获取缓存的用户信息
    List<UserModel> userList = (await UserService.to.getAllUsers()).map((item) {
      debugPrintMap(item);
      return UserModel.fromMap(item);
    }).toList();
    // 取选中的用户信息, 没有则返回nill
    UserModel userModel = userList.firstWhere(
        (element) => element.isSelected == true,
        orElse: () => UserModel.fromMap({}));
    if (userList.isNotEmpty && userModel.isSelected) {
      GlobalService.to.cacheUserInfo.value = userModel;
      LogService.to.info("【$runtimeType】用户信息: ${userModel.toMap()}");
      // 刷新缓存的车辆列表
      await cacheMixinRefreshCacheVehicleList();
    } else {
      LogService.to.info("【$runtimeType】没有缓存的用户信息");
      // 清空缓存的车辆相关全局数据
      GlobalService.to.clearCurrentVehicleGlobalState();
    }
  }

  // 将所有用户设置为未选中
  Future<bool> cacheMixinsetAllUsersUnselected() async {
    List<UserModel> userList = (await UserService.to.getAllUsers()).map((item) {
      return UserModel.fromMap(item);
    }).toList();
    for (var element in userList) {
      await UserService.to.updateUser(
        element.uid,
        isSelected: false,
      );
    }
    return Future(() => true);
  }

  // 判断用户是否存在
  Future<bool> cacheMixinIsUserExist(int uid) async {
    List<UserModel> userList = (await UserService.to.getAllUsers()).map((item) {
      return UserModel.fromMap(item);
    }).toList();
    bool isExist = userList.any((element) => element.uid == uid);
    return Future(() => isExist);
  }

  // 删除用户
  Future<bool> cacheMixinDeleteUser(int uid) async {
    bool deleteState = await UserService.to.cacheMixinDeleteUser(uid);
    await cacheMixinRefreshCacheUserInfo();
    return Future(() => deleteState);
  }

  // MARK: - Vehicle

  // 刷新缓存的车辆列表
  cacheMixinRefreshCacheVehicleList() async {
    final cacheUserInfo = GlobalService.to.cacheUserInfo.value;
    // 获取缓存的车辆信息
    List<VehicleModel> cacheVehicleList =
        (await UserService.to.getVehicles(cacheUserInfo.uid))
            .map((item) => VehicleModel.fromJson(item))
            .toList();
    // 如果缓存车辆列表不为空 && 用户是选中的（退出登录的用户是不用刷新车辆列表，其车辆列表应该为空）
    if (cacheVehicleList.isNotEmpty && cacheUserInfo.isSelected) {
      // 提取选中的车辆
      VehicleModel selectedModel = cacheVehicleList
          .firstWhere((element) => element.isSelected == true, orElse: () {
        // 修改缓存中没有选中的车辆，则默认选中第一辆车辆
        UserService.to.updateVehicle(
          userId: cacheUserInfo.uid,
          bleName: cacheVehicleList.first.bleName,
          isSelected: true,
        );
        return cacheVehicleList.first..isSelected = true;
      });
      // 更新缓存的车辆列表
      GlobalService.to.cacheVehicleList.value = cacheVehicleList;
      GlobalService.to.currentVehicleModel.value = selectedModel;
      GlobalService.to.currentVehicleBleName.value = selectedModel.bleName;
      GlobalService.to.isCurrentVehicleOwner.value =
          selectedModel.isOwner.value;
      for (var i = 0; i < cacheVehicleList.length; i++) {
        debugPrint(
            "【$runtimeType】缓存车辆信息(${i + 1}): ${cacheVehicleList[i].toMap()}");
      }
      // 刷新实时数据
      cacheMixinRefreshCacheVehicleRealtimeData(selectedModel.bleName);
    } else {
      // 清空缓存的车辆相关全局数据
      GlobalService.to.clearCurrentVehicleGlobalState();
    }
  }

  // 判断缓存车辆是否存在
  Future<bool> cacheMixinIsCacheVehicleExist(String bleName) async {
    // 刷新缓存的车辆列表
    await cacheMixinRefreshCacheVehicleList();
    // 判断缓存车辆是否存在
    bool isExist = GlobalService.to.cacheVehicleList
        .any((element) => element.bleName == bleName);
    return Future(() => isExist);
  }

  // 新增缓存车辆 - 用于扫描添加车辆
  Future<VehicleModel?> cacheMixinNewCacheVehicle(
    CustomScanResult scanResult, {
    String? productModel,
  }) async {
    final mills = DateTime.now().millisecondsSinceEpoch;
    // 设置所有车辆为未选中
    return cacheMixinsetAllVehiclesUnselected().then((value) async {
      // 车辆模型
      VehicleModel vehicleModel = GlobalService.to.cacheVehicleList.firstWhere(
          (element) => element.bleName == scanResult.device.advName,
          orElse: () => VehicleModel.fromJson({}));
      Map<String, dynamic> vehicleMap = UserService.to.buildVehicleMap(
        bleName: scanResult.device.advName,
        vehicleName: scanResult.device.advName,
        sn: vehicleModel.sn,
        productModel: productModel ?? vehicleModel.productModel,
        createdStamp: mills,
        updatedStamp: mills,
        connectStamp: mills,
        isSelected: vehicleModel.isSelected,
        firmwareInfo: jsonEncode(
            vehicleModel.firmwareInfoList.map((item) => item.toMap()).toList()),
        isOwner: vehicleModel.isOwner.value,
        tboxStatus: vehicleModel.tboxStatus.value.rawValue,
        hmicStatus: vehicleModel.hmicStatus == true ? 1 : 0,
      );
      // 新增或更新缓存车辆
      bool addSuccess = await UserService.to
          .newVehicle(vehicleMap, GlobalService.to.cacheUserInfo.value.uid);
      if (addSuccess) {
        // 刷新缓存的车辆列表
        await cacheMixinRefreshCacheVehicleList();
        return Future(() => VehicleModel.fromJson(vehicleMap));
      } else {
        debugPrint("❌ cacheMixinNewCacheVehicle 失败");
        return null;
      }
    });
  }

  // 已经认证过车主的车辆写入缓存
  Future<void> cacheMixinAuthorizedVehicleWriteToCache(
    List<VehicleModel> vehicleList, {
    bool? isSelected,
  }) async {
    for (var vehicle in vehicleList) {
      await _writeCacheVehicle(
        bleName: vehicle.bleName,
        sn: vehicle.sn,
        productModel: vehicle.productModel,
        connectStamp: vehicle.connectTimeMillis,
        createdStamp: vehicle.createdTimeMillis,
        updatedStamp: vehicle.updatedTimeMillis,
        vehicleName: vehicle.nickname.value,
        isSelected: isSelected,
        isOwner: vehicle.isOwner.value,
        tboxStatus: vehicle.tboxStatus.value.rawValue,
        hmicStatus: vehicle.hmicStatus == true ? 1 : 0,
      );
    }
    // 再将缓存中，但不存在于vehicleList车辆中的isOwner设置为false
    for (var cachedVehicle in GlobalService.to.cacheVehicleList) {
      if (!vehicleList.any((vehicle) => vehicle.sn == cachedVehicle.sn)) {
        await cacheMixinUpdateCacheVehicle(
          cachedVehicle.bleName,
          isOwner: false,
        );
      }
    }
  }

  // 写入缓存车辆
  Future<VehicleModel?> _writeCacheVehicle({
    required String bleName,
    required String sn,
    required String productModel,
    int? createdStamp,
    int? updatedStamp,
    int? connectStamp,
    String? vehicleName,
    bool? isSelected,
    String? firmwareInfo,
    bool? isOwner,
    int? tboxStatus,
    int? hmicStatus,
  }) async {
    Map<String, dynamic> vehicleMap = UserService.to.buildVehicleMap(
      bleName: bleName,
      vehicleName: vehicleName,
      productModel: productModel,
      connectStamp: connectStamp,
      createdStamp: createdStamp,
      updatedStamp: updatedStamp,
      sn: sn,
      isSelected: isSelected,
      firmwareInfo: firmwareInfo,
      isOwner: isOwner,
      tboxStatus: tboxStatus,
      hmicStatus: hmicStatus,
    );
    return UserService.to
        .newVehicle(vehicleMap, GlobalService.to.cacheUserInfo.value.uid)
        .then((addSuccess) async {
      if (addSuccess) {
        // 刷新缓存的车辆列表
        await cacheMixinRefreshCacheVehicleList();
        return Future(() => VehicleModel.fromJson(vehicleMap));
      } else {
        debugPrint("添加/更新缓存车辆失败");
        return null;
      }
    });
  }

  // 更新缓存车辆
  Future<bool> cacheMixinUpdateCacheVehicle(
    String bleName, {
    String? sn,
    String? ownerUid,
    String? productModel,
    String? vehicleName,
    bool? isSelected,
    int? createdStamp,
    int? updatedStamp,
    int? connectStamp,
    String? firmwareInfo,
    bool? isOwner,
    int? tboxStatus,
    int? hmicStatus,
  }) async {
    if (bleName.isEmpty) {
      return Future(() => false);
    }
    // 更新缓存车辆信息
    await UserService.to.updateVehicle(
      userId: GlobalService.to.cacheUserInfo.value.uid,
      bleName: bleName,
      productModel: productModel,
      sn: sn,
      vehicleName: vehicleName,
      isSelected: isSelected,
      connectStamp: connectStamp,
      createdStamp: createdStamp,
      updatedStamp: updatedStamp,
      firmwareInfo: firmwareInfo,
      isOwner: isOwner,
      tboxStatus: tboxStatus,
      hmicStatus: hmicStatus,
    );
    // 刷新缓存的车辆列表
    await cacheMixinRefreshCacheVehicleList();
    return Future(() => true);
  }

  // 将所有车辆设置为未选中
  Future<bool> cacheMixinsetAllVehiclesUnselected() async {
    int uid = GlobalService.to.cacheUserInfo.value.uid;
    List<VehicleModel> vehicleList = (await UserService.to.getVehicles(uid))
        .map((item) => VehicleModel.fromJson(item))
        .toList();
    for (var element in vehicleList) {
      await UserService.to.updateVehicle(
        userId: uid,
        bleName: element.bleName,
        isSelected: false,
      );
    }
    return Future(() => true);
  }

  // 重置云盒的状态 & 人机版的状态
  Future<bool> cacheMixinResetTboxAndHmicStatus() async {
    int uid = GlobalService.to.cacheUserInfo.value.uid;
    List<VehicleModel> vehicleList = (await UserService.to.getVehicles(uid))
        .map((item) => VehicleModel.fromJson(item))
        .toList();
    for (var element in vehicleList) {
      await UserService.to.updateVehicle(
        userId: uid,
        bleName: element.bleName,
        tboxStatus: TBoxStatus.none.rawValue,
        hmicStatus: 0,
      );
    }
    return Future(() => true);
  }

  // 将所有车辆设置为非车主
  Future<bool> cacheMixinsetAllVehiclesUnowner({String? sn}) async {
    int uid = GlobalService.to.cacheUserInfo.value.uid;
    List<VehicleModel> vehicleList = (await UserService.to.getVehicles(uid))
        .map((item) => VehicleModel.fromJson(item))
        .toList();
    for (var element in vehicleList) {
      await UserService.to.updateVehicle(
        userId: uid,
        bleName: element.bleName,
        isOwner: sn == null
            ? false
            : element.sn == sn
                ? false
                : element.isOwner.value,
      );
    }
    // 刷新缓存的车辆列表
    await cacheMixinRefreshCacheVehicleList();
    return Future(() => true);
  }

  // 删除缓存的车辆
  Future<bool> cacheMixinDeleteCacheVehicle(String bleName) async {
    // 删除缓存的车辆
    bool deleteState = await UserService.to
        .deleteVehicle(GlobalService.to.cacheUserInfo.value.uid, bleName);
    // 刷新缓存的车辆列表
    await cacheMixinRefreshCacheVehicleList();
    return Future(() => deleteState);
  }

  // MARK: - Realtime Data

  // 刷新缓存的车辆实时数据列表
  Future<bool> cacheMixinRefreshCacheVehicleRealtimeData(String bleName) async {
    Map<String, dynamic>? realtimeData = await UserService.to
        .getRealtimeDataByBleName(
            GlobalService.to.cacheUserInfo.value.uid, bleName);
    if (realtimeData != null) {
      CacheRealtimeItemModel itemModel =
          CacheRealtimeItemModel.fromMap(realtimeData);
      GlobalService.to.cacheRealtimeItems.value =
          itemModel.itemList ?? <RealtimeItemModel>[];
    }
    return Future(() => true);
  }

  // 新增车辆实时数据的缓存，如果缓存中已经存在该车辆的实时数据，则更新缓存
  Future<bool> cacheMixinCacheMixinNewCacheVehicleRealtimeData(
    String bleName,
    List<Map<String, dynamic>> realtimeItems, {
    String? sn,
    double? estimatedRemainingMileage,
    double? totalMileage,
    double? batteryPercent,
    Map<String, dynamic>? cyclingRecord,
  }) async {
    if (await _mixinCheckExistCacheVehicleRealtimeData(bleName)) {
      // 更新缓存
      return UserService.to
          .updateVehicleRealtimeDataByBleName(
        GlobalService.to.cacheUserInfo.value.uid,
        bleName,
        realtimeItems,
        estimatedRemainingMileage: estimatedRemainingMileage,
        totalMileage: totalMileage,
        batteryPercent: batteryPercent,
        cyclingRecord: cyclingRecord,
      )
          .then((_) {
        return cacheMixinRefreshCacheVehicleRealtimeData(bleName);
      });
    } else {
      // 新增缓存
      return UserService.to
          .newVehicleRealtimeDataByBleName(
        GlobalService.to.cacheUserInfo.value.uid,
        bleName,
        realtimeItems,
        sn: sn,
        estimatedRemainingMileage: estimatedRemainingMileage,
        totalMileage: totalMileage,
        batteryPercent: batteryPercent,
        cyclingRecord: cyclingRecord,
      )
          .then((_) {
        return cacheMixinRefreshCacheVehicleRealtimeData(bleName);
      });
    }
  }

  // 获取缓存的车辆实时数据列表
  Future<CacheRealtimeItemModel?> cacheMixinGetCacheVehicleRealtimeData(
      String bleName) async {
    Map<String, dynamic>? realtimeData = await UserService.to
        .getRealtimeDataByBleName(
            GlobalService.to.cacheUserInfo.value.uid, bleName);
    if (realtimeData != null) {
      return CacheRealtimeItemModel.fromMap(realtimeData);
    } else {
      return null;
    }
  }

  // 判断缓存车辆实时数据是否存在
  Future<bool> _mixinCheckExistCacheVehicleRealtimeData(String bleName) async {
    return await UserService.to.getRealtimeDataByBleName(
            GlobalService.to.cacheUserInfo.value.uid, bleName) !=
        null;
  }
}
